package com.example.JavaWebApi.service.impl.systemImpl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.JavaWebApi.core.reflect.ReflectionHelper;
import com.example.JavaWebApi.mapper.systemMapper.OrginfoMapper;
import com.example.JavaWebApi.model.entity.systemEntity.Orginfo;
import com.example.JavaWebApi.service.systemService.IOrginfoService;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 杨泽
 * @since 2022-06-15
 */
@Service
public class OrginfoServiceImpl extends ServiceImpl<OrginfoMapper, Orginfo> implements IOrginfoService {

    private static final Object locker=new Object();
    @Override
    public List<Orginfo> getOrgTree() {
        List<Orginfo> list=this.baseMapper.selectList(null);
        return ReflectionHelper.convertToTreeList(list,t->t.getParentOrgId()==null||t.getParentOrgId().equals(0),t->t.getId(),t->t.getParentOrgId(),Orginfo.class);
    }

    @Override
    public IPage<Orginfo> getLazyOrgList(Integer parentId,int page,int limit) {
        QueryWrapper<Orginfo> queryWrapper=new QueryWrapper<>();
        queryWrapper.select("*,(case when exists(select 1 from sys_orginfo sub where sub.ParentOrgID=sys_orginfo.Id) then 1 else 0 end) as hasChildren");
        if (parentId==null||parentId.equals(0)){
            queryWrapper.and(wrapper->wrapper.apply("ParentOrgID is null or ParentOrgID=0"));
        }
        else {
            queryWrapper.eq("ParentOrgID",parentId);
        }
        IPage<Orginfo> pageModel=new Page<>(page,limit);
        return this.baseMapper.selectPage(pageModel,queryWrapper);
    }

    @Override
    public boolean create(Orginfo orginfo) {
        synchronized (locker){
            String orgCode=createOrgCode(orginfo.getParentOrgId());
            orginfo.setOrgCode(orgCode);
            return this.baseMapper.insert(orginfo)>0;
        }
    }

    @Override
    public boolean update(Orginfo orginfo) {
        orginfo.setOrgCode(null);
        return this.baseMapper.updateById(orginfo)>0;
    }

    @Override
    public boolean delete(Integer orgId) {
        return this.baseMapper.deleteById(orgId)>0;
    }
    private String createOrgCode(Integer parentOrgId){
        Orginfo parentOrg=this.baseMapper.selectById(parentOrgId);
        if (parentOrg==null){
            QueryWrapper<Orginfo> queryWrapper=new QueryWrapper<>();
            queryWrapper.apply("ParentOrgID is null or ParentOrgID=0");
            return getCode(queryWrapper);
        }
        else {
            QueryWrapper<Orginfo> queryWrapper=new QueryWrapper<>();
            queryWrapper.eq("ParentOrgID",parentOrgId);
            return parentOrg.getOrgCode()+getCode(queryWrapper);
        }
    }
    /**
     * Description: 生成组织机构code 调用此方法必须在调用者上加锁 要不无法保证code的准确性
     * @param queryWrapper
     * @return java.lang.String
     * @author 杨泽
     * @date 2022/6/21 9:29
     */
    private String getCode(QueryWrapper<Orginfo> queryWrapper){
        String code;
        queryWrapper.select("right(max(OrgCode),3) as OrgCode");
        List<Map<String,Object>> maps=this.baseMapper.selectMaps(queryWrapper);
        if (maps.get(0)!=null){
            code=String.valueOf(Integer.valueOf(String.valueOf(maps.get(0).get("OrgCode")))+1);
            while (code.length()<3){
                code="0"+code;
            }
        }
        else {
            code="001";
        }
        return code;
    }
}
